package com.hibase.core.rule.service.ruletable.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.hibase.core.mybatis.service.BaseServiceImpl;
import com.hibase.core.rule.constant.RuleFieldType;
import com.hibase.core.rule.constant.RuleStatus;
import com.hibase.core.rule.entity.ruletable.RuleTable;
import com.hibase.core.rule.entity.ruletable.RuleTableField;
import com.hibase.core.rule.entity.ruletable.vo.RuleTableFieldSearchVO;
import com.hibase.core.rule.entity.ruletableversion.RuleTableVersion;
import com.hibase.core.rule.mapper.ruletable.RuleTableFieldMapper;
import com.hibase.core.rule.service.ruletable.RuleTableFieldService;
import com.hibase.core.rule.service.ruletable.RuleTableService;
import com.hibase.core.rule.service.ruletableversion.RuleTableVersionService;
import com.hibase.common.exception.HibaseAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 动态规则字段表 服务实现类
 * </p>
 *
 * @author hufeng
 * @since 2019-06-10
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class RuleTableFieldServiceImpl extends BaseServiceImpl<RuleTableFieldMapper, RuleTableField> implements RuleTableFieldService {


    @Autowired
    private RuleTableService ruleTableService;

    @Autowired
    private RuleTableVersionService ruleTableVersionService;

    /**
     * 查询动态规则字段表列表
     */
    @Override
    public PageInfo<RuleTableField> selectRuleTableFieldList(RuleTableFieldSearchVO searchVO) {

        return super.page(searchVO, new QueryWrapper<RuleTableField>());
    }

    /**
     * 改变动态规则字段表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRuleTableField(RuleTableField entity) {

        //校验是否为系统默认的字段
        //默认字段允许增加别名
        HibaseAssert.isFalse(RuleFieldType.PRIORITY_FIELD.getKey().equals(entity.getFieldName()) ||
                RuleFieldType.RANGE_LEFT_FIELD.getKey().equals(entity.getFieldName()) && StrUtil.isBlank(entity.getFieldAliasName()) ||
                RuleFieldType.RANGE_RIGHT_FIELD.getKey().equals(entity.getFieldName()) && StrUtil.isBlank(entity.getFieldAliasName()) ||
                RuleFieldType.REMARK_FIELD.getKey().equals(entity.getFieldName()), "保存字段失败，当前字段为系统默认字段");
        RuleTable ruleTable = ruleTableService.getById(entity.getRuleTableId());

        List<RuleTableField> ruleTableFieldList = super.list(new QueryWrapper<RuleTableField>().eq("rule_table_id", entity.getRuleTableId()));

        BigDecimal maxQuery = BigDecimal.ZERO;
        BigDecimal maxValue = BigDecimal.ZERO;

        //找到当前表字段中查找项和值项的最大值
        //区分修改字段和新增字段
        if (StrUtil.isBlank(entity.getId())) {
            //新增字段
            if (ruleTableFieldList.size() > 0) {
                //表已经存在，添加字段，查询表中字段的最大值
                for (int i = 0; i < ruleTableFieldList.size(); i++) {
                    RuleTableField ruleTableField = ruleTableFieldList.get(i);
                    //查找项排序
                    if (RuleFieldType.QUERY.getKey().equals(ruleTableField.getFiledType())) {
                        maxQuery = ruleTableField.getColumnSort();
                    } else if (RuleFieldType.VALUE.getKey().equals(ruleTableField.getFiledType()) && new BigDecimal(RuleFieldType.REMARK.getKey()).compareTo(ruleTableField.getColumnSort()) > 0) {
                        //类型是值项，且columnSort ！= 999
                        //值项排序
                        maxValue = ruleTableField.getColumnSort();
                    }
                }
                //设置当前查找项字段的顺序
                if (RuleFieldType.QUERY.getKey().equals(entity.getFiledType())) {
                    if (null == maxQuery || maxQuery.compareTo(new BigDecimal(RuleFieldType.QUERY_SORT_START_NUMBER.getKey())) < 0) {
                        //查不到查找项最大值则设置查找项初始序号
                        entity.setColumnSort(new BigDecimal(RuleFieldType.QUERY_SORT_START_NUMBER.getKey()));
                    } else {
                        //表中已经存在查找项则自加
                        entity.setColumnSort(maxQuery.add(BigDecimal.ONE));
                    }
                } else if (RuleFieldType.VALUE.getKey().equals(entity.getFiledType())) {
                    //设置当前值项的顺序
                    //maxValue < 300 设初始值为300
                    if (maxValue.compareTo(new BigDecimal("300")) < 0) {
                        entity.setColumnSort(new BigDecimal(RuleFieldType.VALUE_SORT_START_NUMBER.getKey()));
                    } else {
                        //否则 自加
                        entity.setColumnSort(maxValue.add(BigDecimal.ONE));
                    }
                }
            }
        } else {
            //更新字段
            RuleTableField save = super.getById(entity.getId());
            entity.setColumnSort(save.getColumnSort());
        }


        super.store(entity);
    }

    /**
     * 查询动态规则字段表详情
     */
    @Override
    public RuleTableField viewRuleTableField(String id) {

        RuleTableField entity = super.getById(id, true);

        return entity;
    }

    /**
     * 删除动态规则字段表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRuleTableField(List<String> ids) {
        //上线的表禁止删除字段
        RuleTableField tableField = super.getById(ids.get(0));
        RuleTable ruleTable = ruleTableService.getById(tableField.getRuleTableId());

        List<RuleTableVersion> ruleTableVersionList = ruleTableVersionService.list(new QueryWrapper<RuleTableVersion>().eq("id", ruleTable.getId()));
        ruleTableVersionList.forEach(p -> {
            HibaseAssert.isTrue(RuleStatus.RULE_STATUS_CANCEL.getKey().equals(p.getStatus()), "当前表为上线状态，禁止删除字段");
        });
        super.deleteBy(ids);
    }

    /**
     * 重新排序，支持上移，下移
     * 1: 上移时将当前序号和前一个序号交换位置，注意判断序号是否到100
     * 2：下移时将当前序号和后一个序号交换位置，最后一个字段不支持下移
     * 3：系统默认字段不支持移动
     *
     * @param id
     * @param type
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void fieldSort(String id, String type) {
        RuleTableField ruleTableField = super.getById(id);
        HibaseAssert.notNull(ruleTableField, "未查询到记录");
        BigDecimal currentColumnSort = ruleTableField.getColumnSort();
        //查找项首行 ，不能继续上移
        HibaseAssert.isFalse(new BigDecimal(RuleFieldType.QUERY_SORT_START_NUMBER.getKey()).compareTo(currentColumnSort) == 0
                && RuleFieldType.FIELD_MOVE_UP.getKey().equals(type), "移动失败，已经移动到查找项首行");
        //值项第一行
        HibaseAssert.isFalse(new BigDecimal(RuleFieldType.VALUE_SORT_START_NUMBER.getKey()).compareTo(currentColumnSort) == 0
                && RuleFieldType.FIELD_MOVE_UP.getKey().equals(type), "移动失败，已经移动到值项首行");
        //系统默认字段禁止移动
        HibaseAssert.isFalse(RuleFieldType.RANGE_QUERY.getKey().equals(ruleTableField.getFiledType())
                || RuleFieldType.PRIORITY_FIELD.getKey().equals(ruleTableField.getFieldName())
                || RuleFieldType.REMARK_FIELD.getKey().equals(ruleTableField.getFieldName()),"系统默认字段，禁止移动" );

        //查询字段列表
        List<RuleTableField> fieldList = super.list(new QueryWrapper<RuleTableField>().eq("rule_table_id", ruleTableField.getRuleTableId()));
        if (RuleFieldType.FIELD_MOVE_UP.getKey().equals(type)) {
            //和前一个交换顺序
            for (RuleTableField tableField : fieldList) {
                if (ruleTableField.getColumnSort().subtract(BigDecimal.ONE).compareTo(tableField.getColumnSort()) == 0){

                    tableField.setColumnSort(currentColumnSort);
                    super.store(tableField);
                    ruleTableField.setColumnSort(ruleTableField.getColumnSort().subtract(BigDecimal.ONE));
                    super.store(ruleTableField);
                    break;
                }
            }
        }else {
            for (RuleTableField tableField : fieldList) {
                if (ruleTableField.getColumnSort().add(BigDecimal.ONE).compareTo(tableField.getColumnSort()) == 0){

                    tableField.setColumnSort(currentColumnSort);
                    super.store(tableField);
                    ruleTableField.setColumnSort(ruleTableField.getColumnSort().add(BigDecimal.ONE));
                    super.store(ruleTableField);
                    break;
                }
            }
        }


    }
}
